Java基础知识(十六)

Author Avatar
子语 2017 - 11 - 22
  • 在其它设备中阅读本文章

访问控制权限

访问控制权限

Java有四种访问控制权限:public,protected,default,private

No. 范围 public protected default private
1 在同一个类中
2 在同一包的不同类
3 在不同包的子类
4 在不同包的非子类

protected权限与包的定义有关。
范例:定义com.java.demoA.A类

package com.java.demoa;

public class A {
    protected String info = "Hello";
}

范例:定义com.java.demoB.B类

package com.java.demoB;

import com.java.demoa.A;

public class B extends A { // 与A处于不同包中
    public void print() {
        System.out.println("A中的info:" + super.info);
    }
}

范例:测试

package com.java.test;

import com.java.demoB.B;

public class Test {
    public static void main(String[] args) {
        new B().print(); // A中的info:Hello
    }
}

范例:由Test类直接输出A类中的属性

package com.java.test;

import com.java.demoa.A;

public class Test {
    public static void main(String[] args) {
        System.out.println(new A().info); // 报错,无法访问info
    }
}

由于Test与A不在同一个包,并且没有继承关系,所以是无法访问protected权限。

总结:
1.Java的封装性是以private、protected、default三种权限为主;
2.对于权限的选择,建议如下:
·声明属性就用private;
·声明方法就用public;
3.关于命名要求:
· 类名称每个单词的首字母大写,其余字母小写,例如:StudentInfo;
· 属性名称第一个单词字母小写,而后每个单词首字母大写,例如:studentName;
· 方法名称第一个单词字母小写,而后每个单词首字母大写,例如:toString();
· 常量名全部大写,例如:MSG;
· 包名全部小写,例如:com.java.demo

单例设计模式

(1)正常情况下,类只有产生实例化对象后才能操作这个类。
范例:观察程序

package com.java.demo;

class Singleton{
    public void print() {
        System.out.println("Hello World!");
    }
}

public class Demo {
    public static void main(String[] args) {
        Singleton singleton = new Singleton(); // 生成实例化对象
        singleton.print();
    }
}

Singleton类中存在构造方法,没有自定义构造方法时系统会自动生成一个无参无返回值操作的构造方法,即:一个类至少存在一个构造方法。
范例:修改Singleton类定义

package com.java.demo;

class Singleton{

    private Singleton() {} // 构造方法私有化

    public void print() {
        System.out.println("Hello World!");
    }
}

public class Demo {
    public static void main(String[] args) {
        Singleton singleton = new Singleton(); // 报错,无法访问Singleton()
        singleton.print();
    }
}

构造方法私有化后,无法调用构造方法实例化对象。
范例:调用私有化方法
分析步骤:
1.构造方法上使用了private声明,导致构造方法只能内部使用,因此直接在内部实例化对象:

class Singleton{
    Singleton instance = new Singleton();

    private Singleton() {} // 构造方法私有化

    public void print() {
        System.out.println("Hello World!");
    }
}

2.instance是普通属性,普通属性只有实例化对象才可以调用,因此需要使用static声明instance属性,使其不受实例化对象控制。

package com.java.demo;

class Singleton{
    static Singleton instance = new Singleton();

    private Singleton() {} // 构造方法私有化

    public void print() {
        System.out.println("Hello World!");
    }
}

public class Demo {
    public static void main(String[] args) {
        Singleton singleton = Singleton.instance; 
        singleton.print();
    }
}

3.类中属性需要进行封装private static Singleton instance = new Singleton();
4.获取封装的属性要使用getter(),因此要定义一个同样不受实例化对象控制的getter(),使用static定义。

package com.java.demo;

class Singleton{
    private static Singleton instance = new Singleton();

    private Singleton() {} // 构造方法私有化

    public void print() {
        System.out.println("Hello World!");
    }

    public static Singleton getInstance() {
        return instance;
    }
}

public class Demo {
    public static void main(String[] args) {
        Singleton singletonA = Singleton.getInstance();
        Singleton singletonB = Singleton.getInstance();
        System.out.println(singletonA == singletonB); // true
    }
}

上述代码的意义:要限制一个类实例化底下的个数,首先要锁定的是构造方法,因为实例化对象必须调用构造方法 ,那么构造方法私有化,就无法产生新的对象。此时要实例化一个对象,就需要在类中使用static定义一个公共对象 ,并使用static方法返回该对象,这样不论外部调用多少次,最终该类中只产生了一个对象,这就是单例设计模式(Singleton)
(2)单例设计模式有两种形式:饿汉式、懒汉式
上述单例设计模式就属于饿汉式,即在定义Singleton类时就实例化一个对象,不论该对象最后是否被使用。
而懒汉式则是在第一次使用时才进行实例化对象,如果不使用, 就不进行实例化操作。
范例:实现懒汉式

class Singleton{
    private static Singleton instance;

    private Singleton() {} // 构造方法私有化

    public void print() {
        System.out.println("Hello World!");
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

单例设计模式的目的是让该类在整个系统中只有一个实例化对象。

多例设计模式

多例设计模式,可以让一个类产生指定数量的实例化对象。
范例:定义一个表示性别的类

package com.java.demo;

class Sex {
    private String title;
    private static final Sex MALE = new Sex("男");
    private static final Sex FEMALe = new Sex("女");

    private Sex(String title) {
        this.title = title;
    }

    public static Sex getInstance(int ch) {
        switch (ch) {
            case 0:
                return FEMALe;
            case 1:
                return MALE;
            default:
                return null;
        }
    }

    @Override
    public String toString() {
        return this.title;
    }
}

public class Demo {
    public static void main(String[] args) {
        Sex sex = Sex.getInstance(0);
        System.out.println(sex);
    }
}

JDK1.7之前,switch只能判断int或char,由于数字或字符表示不太直观,在1.7增加了String判断。

package com.java.demo;

class Sex {
    private String title;
    private static final Sex MALE = new Sex("男");
    private static final Sex FEMALe = new Sex("女");

    private Sex(String title) {
        this.title = title;
    }

    public static Sex getInstance(String sex) {
        switch (sex) {
            case "woman":
                return FEMALe;
            case "man":
                return MALE;
            default:
                return null;
        }
    }

    @Override
    public String toString() {
        return this.title;
    }
}

如果不想在switch语句中使用String,则可以引入一个标记接口(该方式不好)

package com.java.demo;

class Sex {
    private String title;
    private static final Sex MALE = new Sex("男");
    private static final Sex FEMALe = new Sex("女");

    private Sex(String title) {
        this.title = title;
    }

    public static Sex getInstance(int ch) {
        switch (ch) {
            case 0:
                return FEMALe;
            case 1:
                return MALE;
            default:
                return null;
        }
    }

    @Override
    public String toString() {
        return this.title;
    }
}

interface Choose {
    int WOMAN = 0;
    int MAN = 1;
}
public class Demo {
    public static void main(String[] args) {
        Sex sex = Sex.getInstance(Choose.MAN);
        System.out.println(sex);
    }
}

This blog is under a CC BY-NC-SA 3.0 Unported License
本文链接:http://yov.oschina.io/article/Java/Java Base/Java基础知识(十六)/